package modelo.maestro;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Robot encargado de la fase de ensamblaje de conjuntos. Representa las
 * acciones que puede realizar este robot, como son la recogida de un engranaje,
 * de un eje, la colocaci&oacute;n de los engranajes y los ejes en la estaci&oacute;n de
 * montaje y la recogida y colocaci&oacute;n del conjunto montado en la cinta de
 * transferencia.
 * 
 * @version 1.0
 * @author Globex Inc.
 */
// public class Robot2 implements Runnable {
public class Robot2 extends Thread implements interfazRobot2 {

	//private EstadosRobot2 estado;
	private OrdenesRobot2 orden;
	private boolean orden_ejecutada;
	
	private PosicionesRobot2 posicion;
	
	private boolean deboMorir;

	private long cicloReloj;
	private long t_desplazamiento_reposo;
	private long t_desplazamiento_cinta_transferencia;
	private long t_desplazamiento_soldador;
	private long t_desplazamiento_verificador;
	private long t_desplazamiento_cinta_aceptados;
	private long t_desplazamiento_cinta_rechazados;
	private long t_recoger_montado;
	private long t_recoger_soldado;
	private long t_recoger_verificado;
	private long t_depositar_montado;
	private long t_depositar_soldado;
	private long t_depositar_aceptado;
	private long t_depositar_rechazado;
	
	private Logger _logger = Logger.getLogger("robot.robot2");

	/**
	 * Constructor del robot 2 que contendr&aacute; los par&aacute;metros iniciales del primer
	 * arranque del sistema
	 */
	public Robot2() {
		//estado = EstadosRobot2.EN_REPOSO;
		orden = OrdenesRobot2.QUIETO;
		orden_ejecutada = false;
		
		posicion = PosicionesRobot2.EN_OTRO_SITIO;
		Maestro.cambiarPosicionRobot2(posicion);

		cicloReloj = 1;
		t_desplazamiento_reposo = 1;
		t_desplazamiento_cinta_transferencia = 1;
		t_desplazamiento_soldador = 1;
		t_desplazamiento_verificador = 1;
		t_desplazamiento_cinta_aceptados = 1;
		t_desplazamiento_cinta_rechazados = 1;
		t_recoger_montado = 1;
		t_recoger_soldado = 1;
		t_recoger_verificado = 1;
		t_depositar_montado = 1;
		t_depositar_soldado = 1;
		t_depositar_aceptado = 1;
		t_depositar_rechazado = 1;
		
		deboMorir=false;
	}

	public Robot2(int cicloReloj, int t_recogida_conjunto_montado,
			int t_transporte_colocacion_conjunto_montado,
			int t_transporte_colocacion_conjunto_soldado) {
		this();
		if (cicloReloj > 0) {
			this.cicloReloj = cicloReloj;
		}
		if (t_recogida_conjunto_montado >=0){
			t_desplazamiento_cinta_transferencia=t_recogida_conjunto_montado/2;
			t_recoger_montado=t_recogida_conjunto_montado/2;
		}
		if (t_transporte_colocacion_conjunto_montado >=0){
			t_desplazamiento_soldador=t_transporte_colocacion_conjunto_montado/2;
			t_depositar_montado=t_transporte_colocacion_conjunto_montado/2;
		}
		if (t_transporte_colocacion_conjunto_soldado >=0){
			t_recoger_soldado = t_transporte_colocacion_conjunto_soldado/2;
			t_desplazamiento_verificador = t_transporte_colocacion_conjunto_soldado/2;
			t_desplazamiento_cinta_aceptados = t_transporte_colocacion_conjunto_soldado/2;
			t_desplazamiento_cinta_rechazados = t_transporte_colocacion_conjunto_soldado/2;
			t_recoger_verificado = t_transporte_colocacion_conjunto_soldado/2;
			t_depositar_soldado = t_transporte_colocacion_conjunto_soldado/2;
			t_depositar_aceptado = t_transporte_colocacion_conjunto_soldado/2;
			t_depositar_rechazado = t_transporte_colocacion_conjunto_soldado/2;
		}
		
		deboMorir=false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see modelo.maestro.interfazRobot2#getEstado()
	 */
	/*public EstadosRobot2 getEstado() {
		return estado;
	}*/

	/*private synchronized void setEstado(EstadosRobot2 estado) {
		this.estado = estado;
	}*/

	/*
	 * (non-Javadoc)
	 * 
	 * @see modelo.maestro.interfazRobot2#getOrden()
	 */
	public OrdenesRobot2 getOrden() {
		return orden;
	}
	
	public PosicionesRobot2 getPosicion() {
		return posicion;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see modelo.maestro.interfazRobot2#setOrden(modelo.maestro.OrdenesRobot2)
	 */
	public void setOrden(OrdenesRobot2 orden) {
		synchronized (this.orden) {
			this.orden = orden;
			this.orden_ejecutada = false;
			_logger.info("Orden from above "+orden);
		}
	}

	/*private synchronized void esperarOrdenes() {
		this.orden = OrdenesRobot2.QUIETO;
	}*/

	private void emularCosteTemporal(long tiempo) {
		try {
			_logger.fine("Sleeping "+tiempo+" millis");
			Thread.sleep(tiempo);
			if(Thread.interrupted())
				_logger.warning("I've been interrupted");
		} catch (InterruptedException e) {
			_logger.log(Level.SEVERE,"" , e);
		}
	}

	private void desplazarse(PosicionesRobot2 posicionDestino) {
		//if (this.posicion != posicionDestino) {
			//this.posicion = PosicionesRobot2.EN_OTRO_SITIO;
			this.posicion = posicionDestino;
			Maestro.cambiarPosicionRobot2(posicion);
			
			switch (posicionDestino) {
			case EN_REPOSO:
				_logger.fine("Robot2 desplazandose a Reposo");
				emularCosteTemporal(t_desplazamiento_reposo);
				break;
			case EN_CINTA_TRANSFERENCIA:
				_logger.fine("Robot2 desplazandose a Cinta Transferencia");
				emularCosteTemporal(t_desplazamiento_cinta_transferencia);
				break;
			case EN_SOLDADOR:
				_logger.fine("Robot2 desplazandose a Soldador");
				emularCosteTemporal(t_desplazamiento_soldador);
				break;
			case EN_VERIFICADOR:
				_logger.fine("Robot2 desplazandose a Verificador");
				emularCosteTemporal(t_desplazamiento_verificador);
				break;
			case EN_CINTA_ACEPTADOS:
				_logger.fine("Robot2 desplazandose a Cinta Aceptados");
				emularCosteTemporal(t_desplazamiento_cinta_aceptados);
				break;
			case EN_CINTA_RECHAZADOS:
				_logger.fine("Robot2 desplazandose a Cinta Rechazados");
				emularCosteTemporal(t_desplazamiento_cinta_rechazados);
				break;
			default:
				_logger.fine("Robot2 desplazandose a Otro Sitio");
				emularCosteTemporal(t_desplazamiento_reposo);
				break;
			}
			
			this.posicion = posicionDestino;
			Maestro.cambiarPosicionRobot2(posicion);
		//}
		//System.out.println("Robot2 en posicion");
	}

	private void recoger(PosicionesRobot2 posicionDestino) {
		//if (this.posicion != posicionDestino) {
			this.posicion = posicionDestino;
			Maestro.cambiarPosicionRobot2(posicion);

			switch (posicionDestino) {
				case EN_CINTA_TRANSFERENCIA:
					_logger.fine("Robot2 recogiendo pieza montada");
					emularCosteTemporal(t_recoger_montado);
					break;
				case EN_SOLDADOR:
					_logger.fine("Robot2 recogiendo pieza soldada");
					emularCosteTemporal(t_recoger_soldado);
					break;
				case EN_VERIFICADOR:
					_logger.fine("Robot2 recogiendo pieza verificada");
					emularCosteTemporal(t_recoger_verificado);
					break;
				default:
					_logger.fine("Robot2 no recoge nada");
					break;
			}
		//}
		//System.out.println("Robot2 ha terminado la recogida");
	}

	private void depositar(PosicionesRobot2 posicionDestino) {
		//if (this.posicion != posicionDestino) {
		_logger.fine("Depositando "+posicionDestino);
			this.posicion = posicionDestino;
			Maestro.cambiarPosicionRobot2(posicion);

			switch (posicionDestino) {
				case EN_SOLDADOR:
					emularCosteTemporal(t_depositar_montado);
					break;
				case EN_VERIFICADOR:
					emularCosteTemporal(t_depositar_soldado);
					break;
				case EN_CINTA_ACEPTADOS:
					emularCosteTemporal(t_depositar_aceptado);
					break;
				case EN_CINTA_RECHAZADOS:
					emularCosteTemporal(t_depositar_rechazado);
					break;
				default:
					_logger.fine("No deposita nada");
					break;
			}
		//}
		
		//System.out.println("Robot2 ha terminado la entrega");
	}

	/*private void recogerMontado() {
		// Desplaza brazo hasta cinta de transferencia
		desplazarse(PosicionesRobot2.EN_CINTA_TRANSFERENCIA);
		// Coge conjunto montado
		recoger(PosicionesRobot2.EN_CINTA_TRANSFERENCIA);
	}*/

	/*private void entregarMontadoSoldador() {
		// Desplaza brazo hasta Soldador
		desplazarse(PosicionesRobot2.EN_SOLDADOR);
		// Suelta conjunto montado
		depositar(PosicionesRobot2.EN_SOLDADOR);
	}*/

	/*private void recogerSoldado() {
		// Desplaza brazo hasta Soldador
		desplazarse(PosicionesRobot2.EN_SOLDADOR);
		// Recoge conjunto soldado
		recoger(PosicionesRobot2.EN_SOLDADOR);
	}*/

	/*private void entregarSoldadoVerificador() {
		// Desplaza brazo hasta verificador
		desplazarse(PosicionesRobot2.EN_VERIFICADOR);
		// Suelta conjunto soldado
		depositar(PosicionesRobot2.EN_VERIFICADOR);
	}*/

	/*private void recogerVerificado() {
		// Desplaza brazo hasta verificador
		desplazarse(PosicionesRobot2.EN_VERIFICADOR);
		// Recoge conjunto verificado
		recoger(PosicionesRobot2.EN_VERIFICADOR);
	}*/

	/*private void entregarVerificadoRechazado() {
		// Desplaza brazo hasta cinta rechazos
		desplazarse(PosicionesRobot2.EN_CINTA_RECHAZADOS);
		// Suelta conjunto rechazado
		depositar(PosicionesRobot2.EN_CINTA_RECHAZADOS);
	}*/

	/*private void entregarVerificadoAceptado() {
		// Desplaza brazo hasta cinta aceptados
		desplazarse(PosicionesRobot2.EN_CINTA_ACEPTADOS);
		// Suelta conjunto aceptado
		depositar(PosicionesRobot2.EN_CINTA_ACEPTADOS);
	}*/
	
	public void morir(){
		deboMorir=true;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void run() {
		// para ver si tengo que esperar por el ciclo de reloj o no
		long elapsed;
		
		while (!deboMorir) {
			elapsed = System.currentTimeMillis();
			
			// hacer cosas
			switch (this.orden) {
			case QUIETO:
				//System.out.println("Robot2 permanece quieto");
				break;
				
			case COGE_MONTADO:
				_logger.info("Ejecutando "+orden);
				//recogerMontado();
				// Desplaza brazo hasta cinta de transferencia
				desplazarse(PosicionesRobot2.EN_CINTA_TRANSFERENCIA);
				// Coge conjunto montado
				recoger(PosicionesRobot2.EN_CINTA_TRANSFERENCIA);
				this.orden_ejecutada = true;
				break;
				
			case TRANSPORTA_MONTADO_SOLDADOR:
				_logger.info("Ejecutando "+orden);
				//entregarMontadoSoldador();
				// Desplaza brazo hasta Soldador
				desplazarse(PosicionesRobot2.EN_SOLDADOR);
				// Suelta conjunto montado
				depositar(PosicionesRobot2.EN_SOLDADOR);
				this.orden_ejecutada = true;
				break;
				
			case COGE_SOLDADO:
				_logger.info("Ejecutando "+orden);
				//recogerSoldado();
				// Desplaza brazo hasta Soldador
				desplazarse(PosicionesRobot2.EN_SOLDADOR);
				// Recoge conjunto soldado
				recoger(PosicionesRobot2.EN_SOLDADOR);
				this.orden_ejecutada = true;
				break;
				
			case TRANSPORTA_SOLDADO_VERIFICADOR:
				_logger.info("Ejecutando "+orden);
				//entregarSoldadoVerificador();
				// Desplaza brazo hasta verificador
				desplazarse(PosicionesRobot2.EN_VERIFICADOR);
				// Suelta conjunto soldado
				depositar(PosicionesRobot2.EN_VERIFICADOR);
				this.orden_ejecutada = true;
				break;
				
			case COGE_VERIFICADO:
				_logger.info("Ejecutando "+orden);
				//recogerVerificado();
				// Desplaza brazo hasta verificador
				desplazarse(PosicionesRobot2.EN_VERIFICADOR);
				// Recoge conjunto verificado
				recoger(PosicionesRobot2.EN_VERIFICADOR);
				this.orden_ejecutada = true;
				break;
				
			case TRANSPORTA_VERFICADO_ACEPTADOS:
				_logger.info("Ejecutando "+orden);
				//entregarVerificadoAceptado();
				// Desplaza brazo hasta cinta aceptados
				desplazarse(PosicionesRobot2.EN_CINTA_ACEPTADOS);
				// Suelta conjunto aceptado
				depositar(PosicionesRobot2.EN_CINTA_ACEPTADOS);
				this.orden_ejecutada = true;
				break;
				
			case TRANSPORTA_VERIFICADO_RECHAZADOS:
				_logger.info("Ejecutando "+orden);
				//entregarVerificadoRechazado();
				// Desplaza brazo hasta cinta rechazos
				desplazarse(PosicionesRobot2.EN_CINTA_RECHAZADOS);
				// Suelta conjunto rechazado
				depositar(PosicionesRobot2.EN_CINTA_RECHAZADOS);
				this.orden_ejecutada = true;
				break;
				
			case REPOSA:
				_logger.info("Ejecutando "+orden);
				desplazarse(PosicionesRobot2.EN_REPOSO);
				this.orden_ejecutada = true;
				break;
				
			default:
				break;
			}
			
			elapsed = System.currentTimeMillis() - elapsed; 
			if(elapsed < this.cicloReloj) {
				emularCosteTemporal(this.cicloReloj - elapsed);
			}
			
			synchronized (this.orden) {
				if(this.orden_ejecutada) {
					_logger.info(orden+" ejecutanda. Volviendo a QUIETO");
					this.orden = OrdenesRobot2.QUIETO;
					this.orden_ejecutada = false;
				}
			}
			
			//emularCosteTemporal(1);
			//esperarOrdenes();
		}
	}

	/*public static void main(String[] args) {
		Robot2 t_1000 = new Robot2(100, 10, 10, 10);
		
		System.out.println("Operaciones de prueba:");
		System.out.println("\tRecoge conjunto montado");
		t_1000.recogerMontado();
		
		System.out.println("\tentregarMontadoSoldador");
		t_1000.entregarMontadoSoldador();
		
		System.out.println("\trecogerSoldado");
		t_1000.recogerSoldado();
		
		System.out.println("\tentregarSoldadoVerificador");
		t_1000.entregarSoldadoVerificador();
		
		System.out.println("\trecogerVerificado");
		t_1000.recogerVerificado();
		
		System.out.println("\tentregarVerificadoAceptado");
		t_1000.entregarVerificadoAceptado();
		

		t_1000.emularCosteTemporal(100);
		

		System.out.println("Arranca hilo robot2");
		t_1000.start();
		System.out.println("Hilo robot2 arrancado");
		
		t_1000.setOrden(OrdenesRobot2.COGE_MONTADO);
		t_1000.emularCosteTemporal(40);
		
		t_1000.setOrden(OrdenesRobot2.TRANSPORTA_MONTADO_SOLDADOR);
		t_1000.emularCosteTemporal(40);
		
		t_1000.setOrden(OrdenesRobot2.COGE_SOLDADO);
		t_1000.emularCosteTemporal(40);
		
		t_1000.setOrden(OrdenesRobot2.TRANSPORTA_SOLDADO_VERIFICADOR);
		t_1000.emularCosteTemporal(40);
		
		t_1000.setOrden(OrdenesRobot2.COGE_VERIFICADO);
		t_1000.emularCosteTemporal(40);
		
		t_1000.setOrden(OrdenesRobot2.TRANSPORTA_VERIFICADO_RECHAZADOS);
		t_1000.emularCosteTemporal(40);
		
		t_1000.setOrden(OrdenesRobot2.REPOSA);
		t_1000.emularCosteTemporal(40);
		
		System.out.println("Fin");
		
		t_1000.morir();
	}*/

}// fin clase